package com.example.mybluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelUuid;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.example.mybluetooth.bean.BleDevice;

import java.util.ArrayList;
import java.util.List;


public class BleScanHelper {
    public static ArrayList<BleDevice> mBleDeviceList = new ArrayList<>();
    private Context context;
    //标记当前是否在扫描
    private boolean mScanning = false;
    //工作子线程
    private Handler mHandler;
    //主线程Handler
    private Handler mMainHandler;
    //android 5.0 扫描对象
    private BluetoothLeScanner mBleScanner;
    //5.0 以下扫描回调对象
    private BluetoothAdapter.LeScanCallback mLeScanCallback;
    //5.0及其以上扫描回调对象
    private ScanCallback mScanCallback;
    //5.0扫描配置对象
    private ScanSettings mScanSettings;
    //扫描过滤器列表
    private ArrayList<ScanFilter> mScanFilterList;
    //蓝牙设配器
    private static BluetoothAdapter mBluetoothAdapter;
    //统一的扫描回调对象
    private OnScanListener mListener;


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    // 在构造函数中执行初始化任务，注意方法的权限修饰符，如果
     BleScanHelper(FragmentActivity activity) {
        context = activity;
//      这个构造函数始终没有被调用
         BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
//        要避免manager为空对象
         mBluetoothAdapter = manager != null ? manager.getAdapter() : null;
         //初始化Handler
         initHandler(context);

         //初始化蓝牙回调
         initBluetoothCallBack();
         //初始化蓝牙扫描配置
         initmScanSettings();
         //初始化蓝牙过滤器
         initScanFilter();

    }



    void setOnScanListener(OnScanListener listener) {
        mListener = listener;
    }

    /**
     * 初始化Handler
     */
    private void initHandler(Context context) {
        //初始化工作线程Handler
        final HandlerThread mHandlerThread = new HandlerThread("ScanThread");
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        //初始化主线程Handler
        mMainHandler = new Handler(context.getMainLooper());
    }

    /**
     * 初始化蓝牙回调
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void initBluetoothCallBack() {
        //5.0及其以上扫描回调
        mScanCallback = new ScanCallback() {
            public void onScanResult(int callBackType, @Nullable final ScanResult result) {
                super.onScanResult(callBackType, result);
                //post出去  尽快结束回调
                mMainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if(result!=null){
                            //扫描回调
                            BleDevice mBleDevice=null;
                            if(mListener!=null){
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                    mBleDevice = new BleDevice(result.getDevice(),result.getRssi(),
                                            result.getScanRecord().getBytes(),result.isConnectable(),result.getScanRecord());
//                                    注意这是扫描数据产生的源头，包括是否可以连接的属性信息，其他没有地方再修改该属性
                                } else {
                                    mBleDevice = new BleDevice(result.getDevice(),result.getRssi(),
                                            result.getScanRecord().getBytes(),result.getScanRecord());
                                }
                                }
                                mListener.onNext(mBleDevice);
                            }
                        }
                });
            }
            public void onBatchScanResults(List<ScanResult> results){
                super.onBatchScanResults(results);
            }

            @Override
            public void onScanFailed(int errorCode) {
                super.onScanFailed(errorCode);
                if (errorCode == 2) {
                    Log.e("RickMa", "扫描太频繁");
                }
            }
        };
        //5.0以下扫描回调
        mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
                if(mMainHandler!=null){
                    mMainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (device != null && scanRecord != null){
                                //扫描回调
                                if(mListener!=null){
                                   final BleDevice mBleDevice = new BleDevice(device,rssi,scanRecord);
                                }
                            }
                        }
                    });
                }
            }
        };
    }

    /**
     * 初始化拦截器实现
     * 扫描回调只会返回符合该拦截器UUID的蓝牙设备
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void initScanFilter(){
        ArrayList<ScanFilter> mScanFilterList = new ArrayList<>();
        ScanFilter.Builder builder = new ScanFilter.Builder();
        builder.setServiceUuid(ParcelUuid.fromString("0000fff1-0000-1000-8000-00805f9b34fb"));
        mScanFilterList.add(builder.build());
    }

    /**
     * 初始化蓝牙扫描配置
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void initmScanSettings(){
        //创建ScanSettings的build对象用于设置参数
        ScanSettings.Builder builder = new ScanSettings.Builder();
                //设置功耗平衡模式
                builder.setScanMode(ScanSettings.SCAN_MODE_BALANCED);
        //设置高功耗模式
        //.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)

        //android 6.0添加设置回调类型、匹配模式等
        if(android.os.Build.VERSION.SDK_INT >= 23) {
            //定义回调类型
            builder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
            //设置蓝牙LE扫描滤波器硬件匹配的匹配模式
            builder.setMatchMode(ScanSettings.MATCH_MODE_STICKY);
        }
        //芯片组支持批处理芯片上的扫描
        if (mBluetoothAdapter.isOffloadedScanBatchingSupported()) {
            //设置蓝牙LE扫描的报告延迟的时间（以毫秒为单位）
            //设置为0以立即通知结果
            builder.setReportDelay(0L);
        }
        mScanSettings = builder.build();
    }

    /**
     * 开始扫描蓝牙ble
     */
    void startScanBle(int time){
        try {
            if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
                Log.d("rickma","BleScanHelper中startScanBle()调用的mBluetoothAdapter的值是:"+mBluetoothAdapter+"，isEnabled():"+ (mBluetoothAdapter != null ? mBluetoothAdapter.isEnabled() : false));
                return;
            }
        }catch (Exception e){
            System.out.println("扫描时发生错误："+e.getMessage());
            e.printStackTrace();

        }

        if (!mScanning){
            //android 5.0后
            if(android.os.Build.VERSION.SDK_INT >= 21) {
                //标记当前的为扫描状态
                mScanning = true;
                //获取5.0新添的扫描类
                if (mBleScanner == null){
                    //mBLEScanner是5.0新添加的扫描类，通过BluetoothAdapter实例获取。
                    mBleScanner = mBluetoothAdapter.getBluetoothLeScanner();
                }
                //在子线程中扫描
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        //mScanSettings是ScanSettings实例，mScanCallback是ScanCallback实例，后面进行讲解。
                        //过滤器列表传空，则可以扫描周围全部蓝牙设备
                        if (mBleScanner!=null) mBleScanner.startScan(null,mScanSettings,mScanCallback);
                        //使用拦截器
                        //mBleScanner?.startScan(mScanFilterList,mScanSettings,mScanCallback)
                    }
                });
            } else {
                //标记当前的为扫描状态
                mScanning = true;
                //5.0以下  开始扫描
                //在子线程中扫描
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        //mLeScanCallback是BluetoothAdapter.LeScanCallback实例
                        mBluetoothAdapter.startLeScan(mLeScanCallback);
                    }
                });
            }
            //设置结束扫描
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //关闭ble扫描
                    stopScanBle();
                }
            },time);
        }
    }

    /**
     * 关闭ble扫描
     */
    void stopScanBle(){
        if (mScanning){
            //移除之前的停止扫描post
            mHandler.removeCallbacks(null);
            //停止扫描设备
            if(android.os.Build.VERSION.SDK_INT >= 21) {
                //标记当前的为未扫描状态
                mScanning = false;
                if(mBleScanner!=null) mBleScanner.stopScan(mScanCallback);
            } else {
                //标记当前的为未扫描状态
                mScanning = false;
                //5.0以下  停止扫描
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
            }
            //主线程回调
            mMainHandler.post(new Runnable() {
                @Override
                public void run() {
                    //扫描结束回调
                    if(mListener!=null)  {
                        mListener.onFinish();
                }
            }
            });
        }
    }


//    销毁方法
    void onDestroy() {
        mMainHandler.removeCallbacksAndMessages(null);
        mHandler.removeCallbacksAndMessages(null);
        mHandler.getLooper().quit();
    }

}


//统一的扫描回调接口
interface OnScanListener {
    void onNext(BleDevice device);

    void onFinish();
}